package com.abaaba.project2.service.serviceImpl;

import com.abaaba.project2.bean.*;
import com.abaaba.project2.bean.bo.PermissionPostBo;
import com.abaaba.project2.bean.bo.RoleListBo;
import com.abaaba.project2.bean.vo.GeneralListVo;
import com.abaaba.project2.bean.vo.PermissionsVo;
import com.abaaba.project2.bean.vo.RoleVo;
import com.abaaba.project2.mapper.AdminMapper;
import com.abaaba.project2.mapper.PermissionMapper;
import com.abaaba.project2.mapper.RightMapper;
import com.abaaba.project2.mapper.RoleMapper;
import com.abaaba.project2.service.AdminRoleService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.System;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class AdminRoleServiceImpl implements AdminRoleService {

    @Autowired
    RoleMapper roleMapper;
    @Autowired
    AdminMapper adminMapper;
    @Autowired
    PermissionMapper permissionMapper;
    @Autowired
    RightMapper rightMapper;


    @Override
    public List<RoleVo> getRoleOptions() {

        RoleExample roleExample = new RoleExample();
        RoleExample.Criteria criteria = roleExample.createCriteria();
        criteria.andDeletedEqualTo(false);

        List<Role> roles = roleMapper.selectByExample(roleExample);

        //封装Vo
        List<RoleVo> roleVos = new ArrayList<>();

        for (Role role : roles) {
            RoleVo roleVo = new RoleVo();
            roleVo.setValue(role.getId());
            roleVo.setLabel(role.getName());
            roleVos.add(roleVo);
        }

        return roleVos;
    }

    @Override
    public GeneralListVo<Role> getRoleList(RoleListBo roleListBo) {

        //分页设置
        PageHelper.startPage(roleListBo.getPage(), roleListBo.getLimit());

        //封装example
        RoleExample roleExample = new RoleExample();
        roleExample.setOrderByClause(roleListBo.getSort() + " " + roleListBo.getOrder());
        RoleExample.Criteria criteria = roleExample.createCriteria();
        criteria.andEnabledEqualTo(true);

        if (roleListBo.getName() != null && !"".equals(roleListBo.getName())) {
            criteria.andNameLike("%" + roleListBo.getName() + "%");
        }

        List<Role> roles = roleMapper.selectByExample(roleExample);

        return new GeneralListVo<Role>(roles, (int) new PageInfo<Role>(roles).getTotal());

    }

    @Override
    public Role createRole(Role role) {

        RoleExample roleExample = new RoleExample();
        RoleExample.Criteria criteria = roleExample.createCriteria();
        criteria.andNameEqualTo(role.getName());

        roleMapper.insertSelective(role);

        List<Role> roles = roleMapper.selectByExample(roleExample);

        Role roleVo = roles.get(0);

        return roleVo;
    }

    @Override
    public void updateRole(Role role) {

        Date date = new Date(java.lang.System.currentTimeMillis());
        role.setUpdateTime(date);

        RoleExample roleExample = new RoleExample();
        RoleExample.Criteria criteria = roleExample.createCriteria();
        criteria.andIdEqualTo(role.getId());

        roleMapper.updateByExampleSelective(role, roleExample);
    }

    @Override
    public Integer deleteRole(Role role) {

        //删除管理员角色的时候，需要同时维护管理员的身份
//        但是按照公网的实现，是不允许删除被管理员使用了的身份
        Role deleteMark = new Role();
        deleteMark.setEnabled(false);
        deleteMark.setDeleted(true);

        RoleExample roleExample = new RoleExample();
        RoleExample.Criteria criteria = roleExample.createCriteria();
        criteria.andIdEqualTo(role.getId());

        //仅当没有管理员使用该身份时，才能删除
        //由于数据库设计的太傻逼，以及逆向工程生成的example不提供or方法，因此选择手写
        List<Admin> admins = adminMapper.roleJudge(role.getId());

        if (admins.size() == 0) {
            roleMapper.updateByExampleSelective(deleteMark, roleExample);
            return 1;
        }


        return -1;
    }

    @Override
    public PermissionsVo getPermissions(Integer id) {

        PermissionsVo permissionsVo = new PermissionsVo();

        //先封装id对应的权限
        //有一个特殊情况是超级管理员，权限为*，因此要把所有权限都封装进去
        PermissionExample permissionExample = new PermissionExample();
        PermissionExample.Criteria criteria = permissionExample.createCriteria();
        criteria.andRoleIdEqualTo(id).andDeletedEqualTo(false);

        List<Permission> permissions = permissionMapper.selectByExample(permissionExample);
        List<String> rights = new ArrayList<>();

        for (Permission permission : permissions) {
            rights.add(permission.getPermission());
        }
        if//如果有超级管理员权限,把right表中所有3级权限封装进表
        (rights.contains("*")) {
            RightExample rightExampleFotSuperAdmin = new RightExample();
            RightExample.Criteria criteriaForSuperAdmin = rightExampleFotSuperAdmin.createCriteria();
            criteriaForSuperAdmin.andTypeEqualTo(3);

            List<Right> rightList = rightMapper.selectByExample(rightExampleFotSuperAdmin);
            List<String> rights2 = new ArrayList<>();
            for (Right right : rightList) {
                rights2.add(right.getId());
            }
            //封装进入Vo
            permissionsVo.setAssignedPermissions(rights2);
        } else //如果没有超级管理员权限
        {
            //直接封装进入Vo
            permissionsVo.setAssignedPermissions(rights);
        }


        //再封装所有权限
        //先把表中所有权限查出来
        RightExample rightExample = new RightExample();
        List<Right> rightsRaw = rightMapper.selectByExample(rightExample);
        List<Right> rightLv1 = new ArrayList<>();
        List<Right> rightLv2 = new ArrayList<>();
        List<Right> rightLv3 = new ArrayList<>();
        //按层次分为三个线性表(减少嵌套循环的次数)
        for (Right right : rightsRaw) {
            if (right.getType() == 1) {
                rightLv1.add(right);
            }
            if (right.getType() == 2) {
                rightLv2.add(right);
            }
            if (right.getType() == 3) {
                rightLv3.add(right);
            }
        }

        List<PermissionsVo.SystemPermissionsBean> systemPermissionsBeans = new ArrayList<>();
        //封装
        for (Right right : rightLv1) {
            PermissionsVo.SystemPermissionsBean systemPermissionsBean = new PermissionsVo.SystemPermissionsBean();
            systemPermissionsBean.setId(right.getId());
            systemPermissionsBean.setLabel(right.getLabel());

            List<PermissionsVo.SystemPermissionsBean.ChildrenBeanX> childrenBeanXES = new ArrayList<>();
            for (Right right1 : rightLv2) {
                PermissionsVo.SystemPermissionsBean.ChildrenBeanX childrenBeanX = new PermissionsVo.SystemPermissionsBean.ChildrenBeanX();
                if (right1.getFatherId() == right.getIdKey()) {
                    childrenBeanX.setId(right1.getId());
                    childrenBeanX.setLabel(right1.getLabel());

                    List<PermissionsVo.SystemPermissionsBean.ChildrenBeanX.ChildrenBean> childrenBeans = new ArrayList<>();
                    for (Right right2 : rightLv3) {
                        PermissionsVo.SystemPermissionsBean.ChildrenBeanX.ChildrenBean childrenBean = new PermissionsVo.SystemPermissionsBean.ChildrenBeanX.ChildrenBean();
                        if (right2.getFatherId() == right1.getIdKey()) {
                            childrenBean.setId(right2.getId());
                            childrenBean.setLabel(right2.getLabel());
                            childrenBean.setApi(right2.getApi());

                            childrenBeans.add(childrenBean);
                        }

                    }
                    childrenBeanX.setChildren(childrenBeans);
                    childrenBeanXES.add(childrenBeanX);
                }
            }

            systemPermissionsBean.setChildren(childrenBeanXES);
            systemPermissionsBeans.add(systemPermissionsBean);
        }

        permissionsVo.setSystemPermissions(systemPermissionsBeans);

        return permissionsVo;
    }

    @Override
    public Integer postPermissions(PermissionPostBo permissionPostBo) {
        Date date = new Date(java.lang.System.currentTimeMillis());

        //封装example
        PermissionExample permissionExample = new PermissionExample();
        PermissionExample.Criteria criteria = permissionExample.createCriteria();
        criteria.andRoleIdEqualTo(permissionPostBo.getRoleId());

        //如果是超级管理员身份，则不允许修改拥有的权限
        if (permissionPostBo.getRoleId() == 1) {
            return -1;
        }


        //把这个角色有的权限都查出来
        List<Permission> permissions = permissionMapper.selectByExample(permissionExample);

        //遍历权限和传进来的String做对比（用contain,如果不存在，则标记delete为1，如果存在，看标记是否为1.）
        List<String> permissionsString = permissionPostBo.getPermissions();
        for (Permission permission : permissions) {
            if (permissionsString.contains(permission.getPermission())) {
                if (permission.getDeleted() == true) {
                    PermissionExample permissionExample1 = new PermissionExample();
                    PermissionExample.Criteria criteria1 = permissionExample1.createCriteria();
                    criteria1.andIdEqualTo(permission.getId());
                    permission.setDeleted(false);
                    permission.setUpdateTime(date);
                    permission.setId(null);
                    permissionMapper.updateByExampleSelective(permission, permissionExample1);

                } else {
                    permissionsString.remove(permission.getPermission());
                }
            } else {
                PermissionExample permissionExample1 = new PermissionExample();
                PermissionExample.Criteria criteria1 = permissionExample1.createCriteria();
                criteria1.andIdEqualTo(permission.getId());
                permission.setDeleted(true);
                permission.setUpdateTime(date);
                permission.setId(null);
                permissionMapper.updateByExampleSelective(permission, permissionExample1);
            }
        }
        //此时List<String>中剩下的就是新权限，插入即可
        for (String s : permissionsString) {
            Permission permission = new Permission();
            permission.setAddTime(date);
            permission.setUpdateTime(date);
            permission.setDeleted(false);
            permission.setPermission(s);
            permission.setRoleId(permissionPostBo.getRoleId());
            permissionMapper.insertSelective(permission);
        }

        return 1;
    }
}
